package com.dragon.modules.yuegou.service.impl.merchant;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.common.web.PageRequest;
import com.dragon.modules.yuegou.client.wechat.client.WxUserClient;
import com.dragon.modules.yuegou.client.wechat.model.WXUserModel;
import com.dragon.modules.yuegou.client.wechat_mini.common.MiniConfig;
import com.dragon.modules.yuegou.client.wechat_mini.service.MiniService;
import com.dragon.modules.yuegou.client.wechat_mini.service.impl.MiniServiceImpl;
import com.dragon.modules.yuegou.entity.busd.BtypeEntity;
import com.dragon.modules.yuegou.entity.busd.DistrictEntity;
import com.dragon.modules.yuegou.entity.merchant.BankEntity;
import com.dragon.modules.yuegou.entity.merchant.MerchantEntity;
import com.dragon.modules.yuegou.entity.merchant.MerchantGroupEntity;
import com.dragon.modules.yuegou.entity.merchant.UserEntity;
import com.dragon.modules.yuegou.entity.merchant.WechatEntity;
import com.dragon.modules.yuegou.enums.busd.BtypeSourceType;
import com.dragon.modules.yuegou.enums.busd.DistrictIsContract;
import com.dragon.modules.yuegou.enums.code.DistrictCode;
import com.dragon.modules.yuegou.enums.code.MerchantCode;
import com.dragon.modules.yuegou.enums.code.WalletCode;
import com.dragon.modules.yuegou.enums.member.FavoriteType;
import com.dragon.modules.yuegou.enums.merchant.MerchantMerType;
import com.dragon.modules.yuegou.enums.merchant.MerchantStatus;
import com.dragon.modules.yuegou.enums.merchant.UserMerchantType;
import com.dragon.modules.yuegou.excel.merchant.MerchantWorkbook;
import com.dragon.modules.yuegou.mapper.merchant.MerchantMapper;
import com.dragon.modules.yuegou.model.busd.District;
import com.dragon.modules.yuegou.model.member.Member;
import com.dragon.modules.yuegou.model.merchant.ArchitectureTree;
import com.dragon.modules.yuegou.model.merchant.Bank;
import com.dragon.modules.yuegou.model.merchant.GroupDistrictBtypeTree;
import com.dragon.modules.yuegou.model.merchant.Merchant;
import com.dragon.modules.yuegou.model.merchant.MerchantPayConfig;
import com.dragon.modules.yuegou.model.merchant.MerchantTree;
import com.dragon.modules.yuegou.model.merchant.PosterAppInfo;
import com.dragon.modules.yuegou.model.merchant.Qrcode;
import com.dragon.modules.yuegou.model.merchant.User;
import com.dragon.modules.yuegou.model.merchant.Wechat;
import com.dragon.modules.yuegou.model.system.Application;
import com.dragon.modules.yuegou.model.system.Dict;
import com.dragon.modules.yuegou.model.system.Document;
import com.dragon.modules.yuegou.model.wallet.MerchantWallet;
import com.dragon.modules.yuegou.properties.PostersProperties;
import com.dragon.modules.yuegou.query.busd.BtypeQuery;
import com.dragon.modules.yuegou.query.member.FavoriteQuery;
import com.dragon.modules.yuegou.query.merchant.BankQuery;
import com.dragon.modules.yuegou.query.merchant.MerchantGroupQuery;
import com.dragon.modules.yuegou.query.merchant.MerchantInfoQuery;
import com.dragon.modules.yuegou.query.merchant.MerchantQuery;
import com.dragon.modules.yuegou.query.merchant.QrcodeQuery;
import com.dragon.modules.yuegou.query.merchant.UserQuery;
import com.dragon.modules.yuegou.query.merchant.WechatQuery;
import com.dragon.modules.yuegou.query.wallet.MerchantWalletQuery;
import com.dragon.modules.yuegou.service.busd.BtypeService;
import com.dragon.modules.yuegou.service.busd.DistrictService;
import com.dragon.modules.yuegou.service.member.FavoriteService;
import com.dragon.modules.yuegou.service.member.MemberService;
import com.dragon.modules.yuegou.service.merchant.BankService;
import com.dragon.modules.yuegou.service.merchant.MerchantGroupService;
import com.dragon.modules.yuegou.service.merchant.MerchantService;
import com.dragon.modules.yuegou.service.merchant.MerchantShortUrlService;
import com.dragon.modules.yuegou.service.merchant.QrcodeService;
import com.dragon.modules.yuegou.service.merchant.UserService;
import com.dragon.modules.yuegou.service.merchant.WechatService;
import com.dragon.modules.yuegou.service.system.ApplicationService;
import com.dragon.modules.yuegou.service.system.DictService;
import com.dragon.modules.yuegou.service.system.DocumentService;
import com.dragon.modules.yuegou.service.wallet.MerchantWalletService;
import com.dragon.modules.yuegou.utils.PageToResultUtils;
import com.dragon.modules.yuegou.utils.PostersUtils;
import com.dragon.modules.yuegou.utils.QRCodeUtil;
import com.dragon.modules.yuegou.web.Check;
import com.dragon.modules.yuegou.web.DataSliceUtils;
import com.dragon.modules.yuegou.web.Tree;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 商户信息 服务实现
 *
 * @author pbuilder generated
 * @date 2019-07-30 09:57:34
 * @version 2.0
 */
@Slf4j
@Service("merMerchantService")
public class MerchantServiceImpl extends ServiceImpl<MerchantMapper, MerchantEntity>
		implements MerchantService {

	@Autowired
	private QrcodeService qrcodeService;

	@Autowired
	private BtypeService btypeService;

	@Autowired
	private DistrictService districtService;
	
	@Autowired
	private PostersProperties postersProperties;

	@Autowired
	private UserService userService;

	@Autowired
	private FavoriteService favoriteService;

	@Autowired
	private MerchantGroupService merchantGroupService;

	@Autowired
	private com.dragon.modules.yuegou.service.system.UserService sysUserService;

	@Autowired
	private MerchantShortUrlService merchantShortUrlService;

	@Autowired
	private ApplicationService applicationService;
	
	@Autowired
	private MemberService memberService;
	
	@Autowired
	private DocumentService documentService;

	@Autowired
	private BankService bankService;

    @Autowired
    private DictService dictService;

    @Autowired
	private WxUserClient wxUserClient;

    @Autowired
	private WechatService wechatService;

    @Autowired
	private MerchantWalletService merchantWalletService;
	
	@Override
	public Merchant merchantDetail(String merchantId) {
		MerchantEntity merchant = getById(merchantId);
		return new Merchant(merchant);
	}
	
	@Override
	public List<Merchant> listBySpuId(String spuId) {
		return baseMapper.listBySpuId(spuId);
	}

	@Override
	public IPage<Merchant> listBySpuId(IPage<MerchantEntity> page, String spuId) {
		return baseMapper.listBySpuId(page, spuId);
	}

	@Override
	public IPage<Merchant> search(PageRequest page, MerchantInfoQuery query) {
		if (StringUtils.isEmpty(query.getBusdId())) {
			throw new DragonException(DistrictCode.DISTRICT_NOTNULL);
		}
		DistrictEntity district =districtService.getById(query.getBusdId());
		if(DistrictIsContract.YES.equals(district.getIsContract())) {
			query.setSourceType(BtypeSourceType.MASTER.getCode());
		}else {		
			query.setSourceType(BtypeSourceType.YSQ.getCode());
		}
		return baseMapper.search(PageToResultUtils.resultToPage(page), query);
	}

	@Override
	@Transactional
	public String saveMerchant(Merchant merchant) {
		merchantCheck(merchant);
		if (StringUtils.isEmpty(merchant.getId())) {
			addMerchant(merchant);
		} else {
			editMerchant(merchant);
		}
		return merchant.getId();
	}
	
	//保存商户参数检查
	private void merchantCheck(Merchant merchant){
		Check.notNull(merchant.getBusdId(), "商圈id不能为空");
		Check.notEmpty(merchant.getMerchantName(), "商户名称不能为空");
		Check.length(merchant.getMerchantName(), 0, 15, "商户名称长度不能超过15个字");
		Check.notEmpty(merchant.getContactMobile(), "账号不能为空");
		Check.notNull(merchant.getBtypeId(), "一级业态不能为空");
		Check.notNull(merchant.getBtypeSecondId(), "二级业态不能为空");
		Check.notEmpty(merchant.getContactName(), "联系人不能为空");
		Check.notNull(merchant.getMerchantType(), "商户类型不能为空");
		Check.notEmpty(merchant.getMerchantCode(), "铺位号不能为空");
		Check.notNull(merchant.getMerchantAcreage(), "面积不能为空");
		Check.positive(merchant.getMerchantAcreage(), "面积必须是正数");
		Check.digits(merchant.getMerchantAcreage(), 10, 2, "面积格式不正确");
		Check.notEmpty(merchant.getMerchantLogo(), "商户图片不能为空");
//		Check.notEmpty(merchant.getMerchantFloorImg(), "楼层图片不能为空");  1.5.4装修修改
		Check.notEmpty(merchant.getUsername(), "商户用户名不能为空");
		if (StringUtils.isNotEmpty(merchant.getRemarks()) && merchant.getRemarks().length() > 300) {
			throw new DragonException(MerchantCode.THE_NUMBER_OF_WORDS_IN_THE_STORE_PROFILE_EXCEEDS_THE_LIMIT);
		}
	}

	private void editMerchant(Merchant merchant) {
		MerchantEntity m = baseMapper.selectById(merchant.getId());
		MerchantQuery query = new MerchantQuery();
		query.del().eq(false);
		query.setBusdId(merchant.getBusdId());
		query.merchantName().eq(merchant.getMerchantName());
		query.id().ne(merchant.getId());
		// 判断商户名称是否存在
		if (count(query.toQueryWrapper()) > 0) {
			throw new DragonException(MerchantCode.MERCHANT_NAME_EXISTS);
		}
		// 修改商户
		updateById(merchant);
		if (StringUtils.isEmpty(merchant.getImages())){
			baseMapper.clearMerchantImages(merchant.getId());
		}


		//保存商户银行卡
		Bank merchantBank = new Bank();
		merchantBank.setMerchantId(merchant.getId());
		merchantBank.setDel(false);
		merchantBank.setBankName(merchant.getBankName());
		merchantBank.setEncTrueName(merchant.getEncTrueName());
		merchantBank.setEncBankNo(merchant.getEncBankNo());
		merchantBank.setBankCode(merchant.getBankCode());
		saveMerchantBank(merchantBank,merchant.getBusdId());

		//迁移钱包微信支付宝余额到悦卡余额
		if (null != merchant.getMerType() && merchant.getMerType() == MerchantMerType.COMPANY && merchant.getMerType() != m.getMerType()){
			MerchantWallet merchantWallet = merchantWalletService.loadByMerchant(m.getId());
			merchantWallet.setYueCardBought(merchantWallet.getYueCardBought().add(merchantWallet.getWechatAmount()).add(merchantWallet.getAlipayAmount()));
			merchantWallet.setWechatAmount(BigDecimal.ZERO);
			merchantWallet.setAlipayAmount(BigDecimal.ZERO);

			merchantWallet.setWithdrawableYueCardBought(merchantWallet.getWithdrawableYueCardBought().add(merchantWallet.getWithdrawableWechatAmount()).add(merchantWallet.getWithdrawableAlipayAmount()));
			merchantWallet.setWithdrawableWechatAmount(BigDecimal.ZERO);
			merchantWallet.setWithdrawableAlipayAmount(BigDecimal.ZERO);

			MerchantWalletQuery merchantWalletQuery = new MerchantWalletQuery();
			merchantWalletQuery.setId(merchantWallet.getId());
			merchantWalletQuery.setVersion(merchantWallet.getVersion());
			merchantWallet.setVersion(merchantWallet.getVersion()+1);

			if (Boolean.FALSE.equals(merchantWalletService.update(merchantWallet,merchantWalletQuery.toQueryWrapper()))){
				throw new DragonException(WalletCode.REPEAT_TRADE);
			}
		}
	}

	private void addMerchant(Merchant merchant) {
		Check.notEmpty(merchant.getPassword(), "商户密码不能为空");
		Check.notEmpty(merchant.getConfirmPassword(), "商户确认密码不能为空");
		if (!merchant.getPassword().equals(merchant.getConfirmPassword())) {
			throw new DragonException(MerchantCode.MERCHANT_PASSWORD);
		}
		MerchantQuery query = new MerchantQuery();
		query.del().eq(false);
		query.merchantName().eq(merchant.getMerchantName());
		query.setBusdId(merchant.getBusdId());
		// 判断商户名称是否存在
		if (count(query.toQueryWrapper()) > 0) {
			throw new DragonException(MerchantCode.MERCHANT_NAME_EXISTS);
		}

		// 判断商户账号是否存在
		com.dragon.modules.yuegou.query.system.UserQuery sysUserQuery = new com.dragon.modules.yuegou.query.system.UserQuery();
		sysUserQuery.mobile().eq(merchant.getUsername());
		List<com.dragon.modules.yuegou.entity.system.UserEntity> sysUserList = sysUserService.list(sysUserQuery.toQueryWrapper());
		if (CollectionUtils.isNotEmpty(sysUserList)) {
			List<String> sysUserIdList = sysUserList.stream().map(com.dragon.modules.yuegou.entity.system.UserEntity::getId)
					.collect(Collectors.toList());
			UserQuery merchantUserQuery = new UserQuery();
			merchantUserQuery.userId().in(sysUserIdList);
			if (userService.count(merchantUserQuery.toQueryWrapper()) > 0) {
				throw new DragonException(MerchantCode.MOBILE_EXISTS);
			}
		}
		// 添加商户
		merchant.setStatus(MerchantStatus.NORMAL);
		merchant.setDel(false);
		save(merchant);
		// 添加商户二维码
		qrcodeService.saveQrcode(merchant.getId());
		// 添加用户
		userService.createMerchantUser(merchant.getId(), merchant.getMerchantName()
				,merchant.getUsername(), merchant.getBusdId(), merchant.getConfirmPassword(), UserMerchantType.MERCHANT);

		//保存商户银行卡
		Bank merchantBank = new Bank();
		merchantBank.setMerchantId(merchant.getId());
		merchantBank.setDel(false);
		merchantBank.setBankName(merchant.getBankName());
		merchantBank.setEncTrueName(merchant.getEncTrueName());
		merchantBank.setEncBankNo(merchant.getEncBankNo());
		merchantBank.setBankCode(merchant.getBankCode());
		saveMerchantBank(merchantBank,merchant.getBusdId());
		merchant.setId(merchant.getId());
	}

	private void saveMerchantBank(Bank merchantBank, String busdId) {
		String merchantId = merchantBank.getMerchantId();
		BankQuery query = new BankQuery();
		query.setDel(false);
		query.setMerchantId(merchantId);
		List<BankEntity> list = bankService.list(query.toQueryWrapper());
		String bankCode = merchantBank.getBankCode();
		String bankNo = merchantBank.getEncBankNo();
		String encTrueName = merchantBank.getEncTrueName();
		if (CollectionUtils.isNotEmpty(list)) {
            if (StringUtils.isEmpty(bankCode) || StringUtils.isEmpty(bankNo) || StringUtils.isEmpty(encTrueName)) {
				throw new DragonException(MerchantCode.MERCHANT_CARD_NUMBER_INFORMATION_CANNOT_BE_EMPTY);
			}
			if (!bankNo.matches("^\\d{1,30}$") ) {
				throw new DragonException(MerchantCode.BANK_CARD_NUMBER_IS_ONE_TWENTY_DIGITS);
			}
			if ( encTrueName.length() > 20) {
				throw new DragonException(MerchantCode.BANK_ACCOUNT_NAME_WITH_TWENTY_CHINESE_CHARACTERS);
			}
			Dict bank_code = dictService.getDict(bankCode, "bank_code");
			merchantBank.setBankName(bank_code.getText());
			BankEntity bank = list.get(0);
			bank.setBankCode(bankCode);
			bank.setBankName(merchantBank.getBankName());
			bank.setEncBankNo(bankNo);
			bank.setEncTrueName(encTrueName);
			bankService.updateById(bank);
		} else {
			if (StringUtils.isEmpty(bankCode) && StringUtils.isEmpty(merchantBank.getBankName()) && StringUtils.isEmpty(bankNo) && StringUtils.isEmpty(encTrueName)) {
				return;
			} else {
				if (StringUtils.isEmpty(bankCode) || StringUtils.isEmpty(bankNo) || StringUtils.isEmpty(encTrueName)) {
					throw new DragonException(MerchantCode.MERCHANT_CARD_NUMBER_INFORMATION_CANNOT_BE_EMPTY);
				}
				if (!bankNo.matches("^\\d{1,30}$") ) {
					throw new DragonException(MerchantCode.BANK_CARD_NUMBER_IS_ONE_TWENTY_DIGITS);
				}
				if ( encTrueName.length() > 20) {
					throw new DragonException(MerchantCode.BANK_ACCOUNT_NAME_WITH_TWENTY_CHINESE_CHARACTERS);
				}
                Dict bank_code = dictService.getDict(bankCode, "bank_code");
				if (bank_code == null) {
					throw new DragonException(MerchantCode.BANK_NOT_EXIST);
				}
                merchantBank.setBankName(bank_code.getText());
				User user = userService.getUser(merchantId, busdId);
				merchantBank.setUserId(user.getId());
				merchantBank.setDel(false);
				merchantBank.setCreatedTime(LocalDateTime.now());
				bankService.save(merchantBank);
			}
		}
	}

	@Override
	@Transactional
	public void delMerchant(String delBy, String id) {
		Check.notNull(id, "商户id不能为空");
		Check.notNull(delBy, "删除人不能为空");
		// 删除商户
		removeById(id);
		// 删除商户用户
		UserQuery query = new UserQuery();
		query.setMerchantId(id);
		query.setDel(false);

		List<UserEntity> userList = userService.list(query.toQueryWrapper());
		
		User user = new User();
		user.setDel(true);
		user.setDelTime(LocalDateTime.now());
		user.setDelBy(delBy);
		userService.update(user, query.toQueryWrapper());
		
		List<String> merchantSysUserIdList = userList.stream().map(UserEntity::getUserId).collect(Collectors.toList());
		if (CollectionUtils.isNotEmpty(merchantSysUserIdList)) {
			// 删除系统用户
			com.dragon.modules.yuegou.model.system.User sysUser = new com.dragon.modules.yuegou.model.system.User();
			com.dragon.modules.yuegou.query.system.UserQuery userQuery = new com.dragon.modules.yuegou.query.system.UserQuery();
			userQuery.id().in(merchantSysUserIdList);
			sysUser.setDel(true);
			sysUser.setDelTime(LocalDateTime.now());
			sysUser.setDelBy(delBy);
			sysUserService.update(sysUser, userQuery.toQueryWrapper());
		}
	}

	@Override
	public void merchantQRCode(QrcodeQuery qrcodeQuery) {
		Check.notNull(qrcodeQuery.getMerchantId(), "商户id不能为空");
		Check.notNull(qrcodeQuery.getStatus(), "状态不能为空");
		Qrcode qrcode = new Qrcode();
		qrcode.setMerchantId(qrcodeQuery.getMerchantId());
		if (!qrcodeQuery.getStatus()) {
			// 关闭二维码
			qrcode.setStatus(false);
			qrcodeService.updateById(qrcode);
		} else {
			// 开启二维码
			if (qrcodeQuery.getDiscount()==null) {
				throw new DragonException(MerchantCode.MERCHANT_DISCOUNT_NOTNULL);
			}
			try {
				String short_url = merchantShortUrlService.getQRCodeShortUrl(qrcodeQuery.getMerchantId());
				// 生成二维码
				BufferedImage image = QRCodeUtil.createImage(short_url, null, true);
				byte[] resultImageBytes = QRCodeUtil.imageToBytes(image, "jpg");
				// 上传合成图片至阿里云OSS
				String key = System.currentTimeMillis() + ".jpg";
				ByteArrayInputStream resultImageInputStream = new ByteArrayInputStream(resultImageBytes);
				Document document = documentService.upload(key,"jpg", resultImageInputStream);
				if (StringUtils.isEmpty(document.getUrl())) {
					throw new DragonException(MerchantCode.MERCHANT_QRCODE_FAILURE);
				}
				// 保存二维码信息
				qrcode.setDiscount(new BigDecimal("100"));
				qrcode.setLink(short_url);
				qrcode.setQrcodeUrl(document.getUrl());
				qrcode.setShortUrl(short_url);
				qrcode.setStatus(true);
				Qrcode qrCode_ = qrcodeService.getQrcode(qrcode.getMerchantId());
				if (null == qrCode_) {// 不存在/新增 bug-view-3410.html
					qrcodeService.save(qrcode);
				} else {
					qrcodeService.updateById(qrcode);
				}
			} catch (Exception e) {
				log.error(String.format("开启商户二维码，生成二维码异常:%s", e.getMessage()), e);
				throw new DragonException(MerchantCode.MERCHANT_QRCODE_FAILURE);
			}
		}
	}

	@Override
	public MerchantTree getMerchant(String busdId, String groupId) {
		List<MerchantTree> list = new ArrayList<>();
		MerchantTree root = new MerchantTree();
		root.setId("0");
		root.setName("全部");
		list.add(root);
		getMerchantTree(busdId, list);
		Tree<MerchantTree> tree = MerchantTree.buildTree(list);
		MerchantTree.modifyTree(tree, inGroup(groupId));
		log.debug("merchantTree{}", tree);
		return tree.root().element();
	}

	/**
	 * 构造商户树形结构
	 * 
	 * @param busdId
	 * @return
	 */
	private List<MerchantTree> getMerchantTree(String busdId, List<MerchantTree> list) {
		BtypeQuery btypeQuery = new BtypeQuery();
		btypeQuery.setDel(false);
		List<BtypeEntity> btypeList = btypeService.list(btypeQuery.toQueryWrapper());
		List<String> btypeIds = btypeList.stream().map(BtypeEntity::getId).collect(Collectors.toList());
		MerchantQuery merchantQuery = new MerchantQuery();
		merchantQuery.setDel(false);
		merchantQuery.setBusdId(busdId);
		merchantQuery.btypeSecondId().in(btypeIds);
		List<MerchantEntity> merchantList = this.list(merchantQuery.toQueryWrapper());
		for (BtypeEntity btype : btypeList) {
			MerchantTree node = new MerchantTree();
			node.setId(btype.getId());
			node.setParentId(btype.getParentId());
			node.setName(btype.getName());
			node.setType("0");
			list.add(node);
		}
		for (MerchantEntity merchant : merchantList) {
			MerchantTree node = new MerchantTree();
			node.setId(merchant.getId());
			node.setParentId(merchant.getBtypeSecondId());
			node.setName(merchant.getMerchantName());
			node.setType("1");
			list.add(node);
		}
		return list;
	}

	private Predicate<MerchantTree> inGroup(String groupId) {
		MerchantGroupQuery query = new MerchantGroupQuery();
		query.setGroupId(groupId);
		query.setDel(false);
		List<MerchantGroupEntity> list = merchantGroupService.list(query.toQueryWrapper());
		Set<String> merchantIds = list.stream().map(MerchantGroupEntity::getMerchantId).collect(Collectors.toSet());
		return node -> merchantIds.contains(node.getId());
	}

	@Override
	public MerchantTree getMerchantList(String busdId) {
		Check.notEmpty(busdId, DistrictCode.DISTRICT_NOTNULL.getMessage());
		List<MerchantTree> list = new ArrayList<>();
		District district = districtService.getDistrictById(busdId);
		MerchantTree root = new MerchantTree();
		root.setId("0");
		root.setName(district.getBcName());
		list.add(root);
		BtypeQuery btypeQuery = new BtypeQuery();
		btypeQuery.setDel(false);
		List<BtypeEntity> btypeList = btypeService.list(btypeQuery.toQueryWrapper());
		for (BtypeEntity btype : btypeList) {
			MerchantTree node = new MerchantTree();
			node.setId(btype.getId());
			node.setParentId(btype.getParentId());
			node.setName(btype.getName());
			node.setType("0");
			list.add(node);
		}
		Tree<MerchantTree> tree = MerchantTree.buildTree(list);
		MerchantTree.showTree(tree);
		log.debug("merchantTree\n{}", tree);
		return tree.root().element();
	}

	@Override
	public GroupDistrictBtypeTree getPlatformMerchantList() {
		GroupDistrictBtypeTree groupDistrictBtypeTree = new GroupDistrictBtypeTree();
		List<MerchantTree> list = new ArrayList<>();
		MerchantTree root = new MerchantTree();
		root.setId("0");
		root.setName("全部");
		list.add(root);

		// 业态列表
		BtypeQuery btypeQuery = new BtypeQuery();
		btypeQuery.setDel(false);
		List<BtypeEntity> btypeList = btypeService.list(btypeQuery.toQueryWrapper());
		for (BtypeEntity btype : btypeList) {
			MerchantTree node = new MerchantTree();
			node.setId(btype.getId());
			node.setParentId(btype.getParentId());
			node.setName(btype.getName());
			node.setType("2");
			list.add(node);
		}

		Tree<MerchantTree> tree = MerchantTree.buildTree(list);
		MerchantTree.showTree(tree);
		log.debug("merchantTree\n{}", tree);
		return groupDistrictBtypeTree;
	}

	@Override
	public List<Merchant> getMerchantByCardId(String cardId) {
		Check.notNull(cardId, "cardId is required");
		return baseMapper.getMerchantByCardId(cardId);
	}

	@Override
	public Merchant getByOldId(String merchantInfoId) {
		MerchantQuery query = new MerchantQuery();
		query.setMerchantIdOld(merchantInfoId);
		return new Merchant(this.getOne(query.toQueryWrapper()));
	}

	@Override
	public List<Merchant> getMerchantById(String id, String busdId,String merchantName) {
		Check.notNull(id, "id is required");
		return baseMapper.getMerchantById(id, busdId,merchantName);
	}

	@Override
	public List<Merchant> getMerchantById(String groupId, String busdId, String btypeId, String merchantName) {
		if (StringUtils.isEmpty(groupId) && StringUtils.isEmpty(busdId)) {
			throw new DragonException(DistrictCode.DISTRICT_NOTNULL);
		}
		return baseMapper.getMerchantByIds(groupId, busdId, btypeId,merchantName);
	}

	@Override
	public Merchant info(String merchantId,String memberId) {
		Merchant merchant = new Merchant(this.getById(merchantId));
		// 统计该商户会员关注信息
		FavoriteQuery query = new FavoriteQuery();
		query.setObjectId(merchantId);
		query.setDel(false);
		query.setType(FavoriteType.BUSINESS);
		Long count = favoriteService.count(query.toQueryWrapper());
		// 设置粉丝值
		merchant.setFrdcount(count.intValue());
		
		if(!StringUtils.isEmpty(memberId)) {
			//获取当前登录用户是否收藏了该店铺
			FavoriteQuery favoriteQuery = new FavoriteQuery();
			favoriteQuery.setMemberId(memberId);
			favoriteQuery.setObjectId(merchantId);
			favoriteQuery.setType(FavoriteType.BUSINESS);
			favoriteQuery.setDel(false);
			Long favoriteCount = favoriteService.count(favoriteQuery.toQueryWrapper());
			merchant.setMemberFavorite(favoriteCount > 0? true : false);
		}
		return merchant;
	}

	@Override
	public IPage<Merchant> searchFeeRatio(PageRequest page, String busdId, String merchantName) {
		Check.notNull(busdId, DistrictCode.DISTRICT_NOTNULL.getMessage());
		return baseMapper.searchFeeRatio(PageToResultUtils.resultToPage(page), busdId, merchantName);
	}

	@Override
	public void setFee(String id, BigDecimal selfFeeRatio, String description) {
		Check.notNull(id, "商户id不能为空");
		Check.notNull(selfFeeRatio, "费率不能为空");
		Check.digits(selfFeeRatio, 1, 2, "费率格式不正确");
		Check.positive(selfFeeRatio, "费率必须是正数");
		if (selfFeeRatio.compareTo(new BigDecimal(0)) < 1 || selfFeeRatio.compareTo(new BigDecimal(1)) > -1) {
			throw new DragonException(MerchantCode.FEE_LV);
		}
		Merchant merchant = new Merchant();
		merchant.setId(id);
		merchant.setSelfFeeRatio(selfFeeRatio);
		merchant.setDescription(description);
		this.updateById(merchant);
	}

	@Override
	public IPage<Merchant> merchantList(PageRequest page, MerchantQuery query) {
		return page(PageToResultUtils.resultToPage(page), query.toQueryWrapper());
	}

	@Override
	public BigDecimal getFeeRatio(String merchantId) {
		Merchant merchant = getMerchantById(merchantId);
		if (merchant.getFeeRatio() != null) {
			return merchant.getFeeRatio();
		}

		BtypeEntity btype = btypeService.getById(merchant.getBtypeId());
		if (btype.getFeeRatio() != null) {
			return btype.getFeeRatio();
		}
		return BigDecimal.ZERO;
	}

	@Override
	public IPage<Merchant> tspuMerchantList(PageRequest page, String spuId) {
		return baseMapper.tspuMerchantList(PageToResultUtils.resultToPage(page), spuId);
	}

	@Override
	public Merchant getMerchantById(String id) {
		Check.notNull(id, "商户列表不能为空");
		return baseMapper.getMerchantByMerId(id);
	}

	@Override
	public IPage<Merchant> findMerchantInfoList(PageRequest page, MerchantInfoQuery query) {
		if (StringUtils.isEmpty(query.getUserId())) {
			return null;
		}
		return baseMapper.findMerchantInfoList(PageToResultUtils.resultToPage(page), query);

	}

	@Override
	public IPage<Merchant> findMerchantList(PageRequest page, MerchantInfoQuery query) {
		if (StringUtils.isEmpty(query.getUserId())) {
			return null;
		}
		if (CollectionUtils.isEmpty(query.getTimeList())) {
			return null;
		}
		if (CollectionUtils.isEmpty(query.getGroupList())) {
			return null;
		}
		return baseMapper.findMerchantList(PageToResultUtils.resultToPage(page), query);

	}

	@Override
	public Integer countMerchantList(MerchantInfoQuery query) {
		if (StringUtils.isEmpty(query.getUserId())) {
			return 0;
		}
		if (CollectionUtils.isEmpty(query.getTimeList())) {
			return 0;
		}
		if (CollectionUtils.isEmpty(query.getGroupList())) {
			return 0;
		}
		return baseMapper.countMerchantList(query);
	}

	@Override
	public Merchant getMerchantInfo(String merchantId, String userId) {
		return baseMapper.getMerchantInfo(merchantId, userId);
	}

	@Override
	public void merchantPayConfig(MerchantPayConfig payConfig) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public IPage<Merchant> recommendMerchantList(PageRequest pageInfo,String busdId) {
		return baseMapper.recommendMerchantList(PageToResultUtils.resultToPage(pageInfo),busdId);
	}


	@Override
	public String yueDianposters(String merchantId, String appid, PosterAppInfo info, String memberId) {
		Merchant merchant = getMerchantById(merchantId);
		if (merchant != null) {
			info.setAppPath(String.format(postersProperties.getYuedianPath(), merchant.getId(), merchant.getBusdId()));
			Application application = applicationService.getByAppid(appid);
			MiniService service = new MiniServiceImpl(new MiniConfig(application.getAppid(), application.getAppsecret()));

			byte[] qRCodeBytes = service.wxaCode().createQRCode(info.getAppPath(), 140);
			Member member = memberService.getMember(memberId);
			ByteArrayInputStream resultImageInputStream = new PostersUtils().getYueDianPosters(qRCodeBytes, merchant,
					info, member.getHeadImg());
			Document document = documentService.upload(merchant.getMerchantName(), "png", resultImageInputStream);
			return document.getUrl();
		}
		return "";
	}

	@Override
	public ArchitectureTree architectureTree(String busdId) {
		//查询商圈信息
		DistrictEntity district = districtService.getById(busdId);
		//查询商圈下商户
		MerchantQuery query = new MerchantQuery();
		query.setBusdId(busdId);
		query.setDel(false);
		List<MerchantEntity> list = list(query.toQueryWrapper());
		List<ArchitectureTree> collect = list.stream().map(merchant -> {
			ArchitectureTree tree = new ArchitectureTree();
			tree.setId(merchant.getId());
			tree.setLevel(4);
			tree.setName(merchant.getMerchantName());
			return tree;
		}).collect(Collectors.toList());
		List<ArchitectureTree> groupMerchant = new ArrayList<ArchitectureTree>();
		ArchitectureTree group = new ArchitectureTree();
		group.setId("1");
		group.setLevel(3);
		group.setName("平台实物");
		ArchitectureTree merchant = new ArchitectureTree();
		merchant.setId("3");
		merchant.setLevel(3);
		merchant.setName("商户实物");
		merchant.setTrees(collect);
		groupMerchant.add(merchant);
		groupMerchant.add(group);
		ArchitectureTree tree = new ArchitectureTree();
		tree.setId(district.getId());
		tree.setLevel(1);
		tree.setName(district.getBcName());
		List<ArchitectureTree> upperLower = new ArrayList<ArchitectureTree>();
		ArchitectureTree upper = new ArchitectureTree();
		upper.setId("1");
		upper.setLevel(2);
		upper.setName("上架");
		upper.setTrees(groupMerchant);
		ArchitectureTree lower = new ArchitectureTree();
		lower.setId("0");
		lower.setLevel(2);
		lower.setName("下架");
		lower.setTrees(groupMerchant);
		upperLower.add(lower);
		upperLower.add(upper);
		tree.setTrees(upperLower);
		return tree;
	}

	@Override
	public Map<String, Object> bindWechat(String id, String code, Application application) {
		WXUserModel wxUserModel = wxUserClient.userInfo(code,application.getAppid(),application.getAppsecret());

		WechatQuery wechatQuery1 = new WechatQuery();
		wechatQuery1.merchantId().eq(id);
		WechatEntity wechat1 = wechatService.getOne(wechatQuery1.toQueryWrapper());
		if (null == wechat1){
			wechat1 = new Wechat();
			wechat1.setMerchantId(id);
		}
		BeanUtils.copyProperties(wxUserModel,wechat1);
		wechatService.save(wechat1);
		Map<String, Object> map = new HashMap<>();
		map.put("nickName",wxUserModel.getNickname());
		return map;
	}

	@Override
	public Document exportMerchant(MerchantInfoQuery query) {
		if (StringUtils.isEmpty(DataSliceUtils.currentBusdId())) {
			throw new DragonException(DistrictCode.DISTRICT_NOTNULL);
		}
		DistrictEntity district =districtService.getById(DataSliceUtils.currentBusdId());
		if(DistrictIsContract.YES.equals(district.getIsContract())) {
			query.setSourceType(BtypeSourceType.MASTER.getCode());
		}else {
			query.setSourceType(BtypeSourceType.YSQ.getCode());
		}
		query.setBusdId(district.getId());
		List<Merchant> merchantList =baseMapper.search(query);

		MerchantWorkbook merchantWorkbook = new MerchantWorkbook();
		List<MerchantWorkbook.MerchantRow> merchantRows = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(merchantList)) {
			List<User> userList = userService.busdUserList(query.getBusdId());
			Map<String,List<User>> userMap = userList.stream().collect(Collectors.groupingBy(User::getMerchantId));

			for (Merchant merchant : merchantList){
				MerchantWorkbook.MerchantRow merchantRow = new MerchantWorkbook.MerchantRow();
				merchantRow.setId(merchant.getId());
				merchantRow.setMerchantName(merchant.getMerchantName());
				List<User> users = userMap.get(merchant.getId());
				if (CollectionUtils.isNotEmpty(users)){
					merchantRow.setAccount(users.get(0).getMobile());
				}
				merchantRow.setbName(merchant.getbName());
				merchantRow.setbSecondName(merchant.getbSecondName());
				merchantRow.setContactAddress(merchant.getContactAddress());
				merchantRow.setContactMobile(merchant.getContactMobile());
				merchantRow.setContactName(merchant.getContactName());
				merchantRows.add(merchantRow);
			}
		}
		merchantWorkbook.setMerchantRowList(merchantRows);
		return documentService.generateExcel("商户表", merchantWorkbook);
	}

	@Override
	public List<Merchant> getOwnerTypeMerchantList(String busdId,Integer... skuType) {
		List<Integer> skuTypeList = Arrays.asList(skuType);
		return baseMapper.getOwnerTypeMerchantList(busdId,skuTypeList);
	}
}